home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / ddj0897.zip / DYN401.ZIP / utils / win32 / cp.c next >
C/C++ Source or Header  |  1995-08-27  |  6KB  |  290 lines

  1.  
  2. /*
  3.  *
  4.  *    Copyright 1993 Algorithms Corporation
  5.  *
  6.  *    ALL RIGHTS RESERVED.
  7.  *
  8.  *
  9.  *
  10.  */
  11.  
  12.  
  13. #include <windows.h>
  14. #include <stdio.h> 
  15. #include <sys/types.h>
  16. #include <sys/stat.h>
  17. #include <fcntl.h>
  18. #include <io.h>
  19. #include <malloc.h>
  20. #include <dos.h>
  21. #include <errno.h>
  22.  
  23.  
  24. static    void    strip_path(), print_error();
  25. static    void    usage();
  26. static    int    copy_file();
  27.  
  28. #define    here    fprintf(stderr, "%s (%d)\n", __FILE__, __LINE__);
  29.  
  30. int    main(argc, argv)
  31. int    argc;
  32. char    *argv[];
  33. {
  34.     int    r, i, isdir, err=0, quiet=0, verbose=0, existing=0, zero=0;
  35.     int    recurse=0;
  36.     char    buf[128], tmp[128];
  37.     
  38.     if (argc < 3)
  39.         usage();
  40.     isdir = isDir(argv[argc-1]);
  41.     argc--;
  42.     for ( ; 1 < argc  &&  argv[1][0] == '-' ; argc--, argv++)
  43.         for (r=1 ; argv[1][r] ; ++r)
  44.             switch (argv[1][r])  {
  45.             case 'e':
  46.             case 'E':
  47.                 existing = 1;
  48.                 break;
  49.             case 'q':
  50.             case 'Q':
  51.                 quiet = 1;
  52.                 verbose = 0;
  53.                 break;
  54.             case 'r':
  55.             case 'R':
  56.                 recurse = 1;
  57.                 break;
  58.             case 'v':
  59.             case 'V':
  60.                 verbose = 1;
  61.                 quiet = 0;
  62.                 break;
  63.             case 'z':
  64.             case 'Z':
  65.                 zero = 1;
  66.                 break;
  67.             default:
  68.                 fprintf(stderr, "cp:  Unknown flag %c\n", argv[1][r]);
  69.                 break;
  70.             }
  71.     if (!isdir  &&  recurse)  {
  72.         if (makeDir(argv[argc]))  {
  73.             fprintf(stderr, "cp:  Can't create directory %s\n", argv[argc]);
  74.             exit(zero ? 0 : 1);
  75.         }
  76.         isdir = 1;
  77.     }
  78.     if (argc > 2  &&  !isdir  ||  argc < 2)
  79.         usage();
  80.     for (i=1 ; i < argc ; ++i)  {
  81.         if (isdir)  {
  82.             if (recurse  &&  isDir(argv[i]))  {
  83.                 if (copy_dir(argv[i], argv[argc], verbose, existing, quiet))
  84.                     err = 1;
  85.             } else {
  86.                 char    c;
  87.  
  88.                 strip_path(tmp, argv[i]);
  89.                 strcpy(buf, argv[argc]);
  90.                 c = buf[strlen(buf)-1];
  91.                 if (c != '/'  &&  c != '\\'  &&  c != ':')
  92.                     strcat(buf, "/");
  93.                 strcat(buf, tmp);
  94.                 r = copy_file(argv[i], buf, verbose, existing);
  95.                 if (r)  {
  96.                     if (!quiet)
  97.                         print_error(r, argv[i], buf);
  98.                     err = 1;
  99.                 }
  100.             }
  101.         }  else  {
  102.             r = copy_file(argv[i], argv[argc], verbose, existing);
  103.             if (r)  {
  104.                 if (!quiet)
  105.                     print_error(r, argv[i], argv[argc]);
  106.                 err = 1;
  107.             }
  108.         }
  109.     }
  110.     return zero ? 0 : err;
  111. }
  112.  
  113. int    copy_dir(fd, td, verbose, existing, quiet)
  114. char    *fd, *td;
  115. int    verbose, existing, quiet;
  116. {
  117.     char    fpath[80], tdir[80], tpath[80];
  118.     int    r, flg, err=0;
  119.     struct    _finddata_t    fi;
  120.     long    fh;
  121.  
  122.     strip_path(fpath, fd);
  123.     if (!strcmp(fpath, ".")  ||  !strcmp(fpath, ".."))
  124.         return 0;
  125.     if (*fpath)
  126.         sprintf(tdir, "%s/%s", td, fpath);
  127.     else
  128.         strcpy(tdir, td);
  129.     if (makeDir(tdir))  {
  130.         if (!quiet)
  131.             print_error(12, NULL, tdir);
  132.         return 12;
  133.     }
  134.  
  135.  
  136.     r = strlen(fd) - 1;
  137.     if (flg = (fd[r] == ':'  ||  fd[r] == '/'  ||  fd[r] == '\\'))
  138.         sprintf(fpath, "%s*", fd);
  139.     else
  140.         sprintf(fpath, "%s/*", fd);
  141.     fh = _findfirst(fpath, &fi);
  142.     r = fh == -1L;
  143.     while (!r)  {
  144.         if (flg)
  145.             sprintf(fpath, "%s%s", fd, fi.name);
  146.         else
  147.             sprintf(fpath, "%s/%s", fd, fi.name);
  148.         if (isDir(fpath))
  149.             copy_dir(fpath, tdir, verbose, existing, quiet);
  150.         else  {
  151.             sprintf(tpath, "%s/%s", tdir, fi.name);
  152.             r = copy_file(fpath, tpath, verbose, existing);
  153.             if (r)  {
  154.                 if (!quiet)
  155.                     print_error(r, fpath, tpath);
  156.                 err = 1;
  157.             }
  158.         }
  159.         r = _findnext(fh, &fi);
  160.     }
  161.     if (fh != -1L)
  162.         _findclose(fh);
  163.     return err;
  164. }
  165.  
  166. static    void    print_error(r, ff, tf)
  167. int    r;
  168. char    *ff, *tf;
  169. {
  170.     switch (r)  {
  171.     case 1:
  172.         fprintf(stderr, "cp:  source file %s doesn't exist\n", ff);
  173.         break;
  174.     case 2:
  175.         fprintf(stderr, "cp:  can't create %s\n", tf);
  176.         break;
  177.     case 3:
  178.         fprintf(stderr, "cp:  error writing to %s\n", tf);
  179.         break;
  180.     case 4:
  181.         fprintf(stderr, "cp:  error reading %s\n", ff);
  182.         break;
  183.     case 7:
  184.         fprintf(stderr, "cp:  attempt to overwrite existing file %s\n", tf);
  185.         break;
  186.     case 10:
  187.         fprintf(stderr, "cp:  out of memory\n", ff);
  188.         break;
  189.     case 11:
  190.         fprintf(stderr, "cp:  source file %s is a directory\n", ff);
  191.         break;
  192.     case 12:
  193.         fprintf(stderr, "cp:  Can't create directory %s\n", tf);
  194.         break;
  195.     default:
  196.         fprintf(stderr, "cp:  Can't copy %s to %s (error %d)\n", ff, tf, r);
  197.         break;
  198.     }
  199. }
  200.  
  201. static    void    usage()
  202. {
  203.     printf("Usage:\tcp  [-option]  file  file\n"); 
  204.     printf("\tcp  [-option]  file...  directory\n");
  205.     printf("Options:\n");
  206.     printf("\te\tdon't overwrite existing files\n");
  207.     printf("\tq\tquiet (no error messages)\n");
  208.     printf("\tr\trecurse into sub-directories\n");
  209.     printf("\tv\tverbose\n");
  210.     printf("\tz\talways return 0 exit status\n");
  211.     exit(1); 
  212. }
  213.  
  214. static    void    strip_path(to, from)
  215. char    *from, *to;
  216. {
  217.     char    *t;
  218.  
  219.     for (t=from ; *t ; ++t)
  220.         if (*t == '/'  ||  *t == '\\'  ||  *t == ':')
  221.             from = t + 1;
  222.     strcpy(to, from);
  223. }
  224.  
  225. static    int    copy_file(ff, tf, verbose, existing)
  226. char    *ff, *tf;
  227. int    verbose;
  228. int    existing;   /*  don't overwrite existing files  */
  229. {
  230.     
  231.     if (verbose)
  232.         printf("Copying %s -> %s\n", ff, tf);
  233.     return !CopyFile(ff, tf, existing);
  234. }
  235.  
  236. int    makeDir(f)
  237. char    *f;
  238. {
  239.     char    path[100], *p;
  240.     struct    stat    sb;
  241.     
  242.     p = path;
  243.     if (*f  &&  f[1] == ':')  {
  244.         *p++ = *f++;
  245.         *p++ = *f++;
  246.     }
  247.     while (*f)  {
  248.         for (*p++ = *f++ ; *f  &&  *f != '/' && *f != '\\' ; )
  249.             *p++ = *f++;
  250.         *p = '\0';
  251.         if (stat(path, &sb))  {  /*  path doesn't exist  */
  252.             if (mkdir(path))
  253.                 return 1;   /*  can't create  */
  254.         } else if (!(sb.st_mode&S_IFDIR))
  255.             return 1;     /*  not a directory  */
  256.     }
  257.     return(0);
  258. }
  259.  
  260. int    isDir(f)
  261. char    *f;
  262. {
  263.     struct    stat    sb;
  264.     char    buf[5];
  265.  
  266.     if (*f  &&  f[1] == ':'  &&  !f[2])  {
  267.         strcpy(buf, f);
  268.         strcat(buf, ".");
  269.         f = buf;
  270.     }
  271.     if (stat(f, &sb))
  272.         return 0;
  273.     return sb.st_mode & S_IFDIR;
  274. }
  275.  
  276.  
  277.  
  278.  
  279. /*
  280.  *
  281.  *    Copyright 1993 Algorithms Corporation
  282.  *
  283.  *    ALL RIGHTS RESERVED.
  284.  *
  285.  *
  286.  *
  287.  */
  288.  
  289.  
  290.